package ch.fusun.baron.core.service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import ch.fusun.baron.core.rmi.User;
import ch.fusun.baron.data.AbstractDataProvider;
import ch.fusun.baron.data.DataListener;
import ch.fusun.baron.data.DataUpdate;
import ch.fusun.baron.data.EmptyUpdate;

/**
 * Default implementation of the user service
 */
public class UserServiceImpl extends AbstractDataProvider implements
		UserService {
	private final List<User> registeredUsers = new ArrayList<User>();
	/**
	 * The users logged in at the moment
	 */
	private final Map<Integer, User> idUserMap = new HashMap<Integer, User>();
	private User currentUser;

	/**
	 * Constructor
	 */
	public UserServiceImpl() {
	}

	@Override
	public void createUser(User user) {
		registeredUsers.add(user);
		for (DataListener listener : getListeners()) {
			if (listener instanceof UserListener) {
				((UserListener) listener).userCreated(user);
			} else {
				listener.dataChanged(new CreateUserDataUpdate(user));
			}
		}
	}

	private User findUser(User user) {
		int index = registeredUsers.indexOf(user);
		if (index != -1) {
			return registeredUsers.get(index);
		}
		return null;
	}

	@Override
	public void login(User user, int id) {
		User persistentUser = findUser(user);
		if (persistentUser != null) {
			if (persistentUser.getPassword().equals(user.getPassword())) {
				idUserMap.put(id, persistentUser);
				for (DataListener listener : getListeners()) {
					if (listener instanceof UserListener) {
						((UserListener) listener).userLoggedIn(persistentUser);
					} else {
						listener.dataChanged(new UserLoggedInDataUpdate(user,
								id));
					}
				}
			}
		}
	}

	@Override
	public boolean exists(String name) {
		for (User user : registeredUsers) {
			if (user.getName().equals(name)) {
				return true;
			}
		}
		return false;
	}

	@Override
	public void logout(int id) {
		User user = idUserMap.get(id);
		if (user != null) {
			idUserMap.remove(id);
			for (DataListener listener : getListeners()) {
				if (listener instanceof UserListener) {
					((UserListener) listener).userLoggedOut(user);
				} else {
					listener.dataChanged(new UserLoggedOutDataUpdate(id));
				}
			}
		}
	}

	@Override
	public boolean isLoggedIn(User user) {
		return idUserMap.containsValue(user);
	}

	@Override
	public Collection<User> getUsers() {
		return registeredUsers;
	}

	@Override
	public User getUser() {
		return this.currentUser;
	}

	@Override
	public void setUser(User user) {
		this.currentUser = user;
	}

	@Override
	public DataUpdate createFullUpdate() {
		return new EmptyUpdate(); // We don't update the user data yet //TODO
									// Should we?
	}

}
